package top.tupobi.zing.mvp.view;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SizeUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.bumptech.glide.Glide;
import com.google.gson.Gson;

import java.io.File;
import java.util.List;

import top.tupobi.zing.InfoRecord;
import top.tupobi.zing.R;
import top.tupobi.zing.ZingApplication;
import top.tupobi.zing.adapter.AdapterRvChat;
import top.tupobi.zing.base.BaseMVPActivity;
import top.tupobi.zing.base.BasePresenter;
import top.tupobi.zing.custom_view.LeftMenu;
import top.tupobi.zing.custom_view.OnLeftMenuListener;
import top.tupobi.zing.listener.OnFriendChooseChangeListener;
import top.tupobi.zing.mvp.model.FriendModel;
import top.tupobi.zing.mvp.model.TbMessage;
import top.tupobi.zing.mvp.presenter.ChatPresenter;
import top.tupobi.zing.network.HttpConfig;
import top.tupobi.zing.service.socket.packet.DataType;
import top.tupobi.zing.utils.LocationUtils;

public class AtyChat extends BaseMVPActivity<ChatPresenter> implements IChatView {

    public static void actionStart(Context context) {
        context.startActivity(new Intent(context, AtyChat.class));
    }

    private Drawable mChatBackgroundDrawable;
    private LeftMenu.Builder mLeftMenuBuilder;
    private boolean mHasCustomBackground;
    private View view_dot;
    private ImageView iv_setting;
    private TextView tv_friend;
    private RecyclerView rv_chat;
    private AdapterRvChat mAdapterRvChat = new AdapterRvChat();
    //    private EditText et_input_message;
    private EditText et_input_message;
    private int mSoftInputHeight;
    private RelativeLayout rl_chat_container, rl_new_message;
    private boolean mIsInputBeTop;
    private int mNavigatorHeight;
    private LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
    private SwipeRefreshLayout srl_chat;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        String chatBackgroundImagePath = InfoRecord.getChatBackgroundImagePath();
        File file = new File(chatBackgroundImagePath);
        // 可能没有文件读写权限，所以还要判断是否可读
        if (file.exists() && file.canRead()) {
            LogUtils.e("file size == " + (float) file.length() / 1024 / 1024);
            Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
            mChatBackgroundDrawable = ImageUtils.bitmap2Drawable(bitmap);
            mHasCustomBackground = true;
        } else {
            mChatBackgroundDrawable = getResources().getDrawable(R.drawable.bg_chat);
        }
        getWindow().getDecorView().setBackgroundDrawable(mChatBackgroundDrawable);
//        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);// 软键盘弹起遮挡edittext
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void initView() {
        ImageView iv_bg = findViewById(R.id.iv_bg);
        tv_friend = findViewById(R.id.tv_friend);
        iv_setting = findViewById(R.id.iv_setting);
        rl_new_message = findViewById(R.id.rl_new_message);
        srl_chat = findViewById(R.id.srl_chat);
        rl_chat_container = findViewById(R.id.rl_chat_container);
        view_dot = findViewById(R.id.view_dot);
        if (mHasCustomBackground) {
            Glide.with(this).load(mChatBackgroundDrawable).into(iv_bg);
        } else {
            Glide.with(this).load(R.drawable.bg_chat).into(iv_bg);
        }
        rv_chat = findViewById(R.id.rv_chat);
        et_input_message = findViewById(R.id.et_input_message);
//        mLinearLayoutManager.setStackFromEnd(true);
        rv_chat.setLayoutManager(mLinearLayoutManager);
        rv_chat.setAdapter(mAdapterRvChat);
        mLeftMenuBuilder = new LeftMenu.Builder(AtyChat.this, rv_chat);


        et_input_message.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            //当键盘弹出隐藏的时候会 调用此方法。
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                //获取当前界面可视部分
                AtyChat.this.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
                //获取屏幕的高度
                int screenHeight = AtyChat.this.getWindow().getDecorView().getRootView().getHeight();
                //此处就是用来获取键盘的高度的， 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
                int currentSoftInputHeight = screenHeight - r.bottom;

                // 这里只取变化的非零高度作为软键盘的高度(考虑到更换软键盘软件)，该高度包含了虚拟按键
                if (currentSoftInputHeight != 0 && currentSoftInputHeight != mSoftInputHeight) {
                    mSoftInputHeight = currentSoftInputHeight;
                    LogUtils.e("软键盘高度 == " + mSoftInputHeight);
                }

                // 记录虚拟按键高度
                if (currentSoftInputHeight < 200) {
                    mNavigatorHeight = currentSoftInputHeight;
                }

                // 该方法键盘一旦打开就会一直回调，所以要过滤不必要的挪动
                if (currentSoftInputHeight != mOldSoftInputHeight) {
                    // 高度变化了，不能按高度为0判断，虚拟按键
                    if (currentSoftInputHeight > 200) {
                        // 可能是虚拟按键，过滤虚拟按键
                        moveUpInput();
                    } else {
                        moveDownInput();
                    }
                }
                mOldSoftInputHeight = currentSoftInputHeight;
            }
        });

        findViewById(R.id.btn_send_message).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String messageStr = et_input_message.getText().toString();
                if ("".equals(messageStr)) {
                    ToastUtils.showShort("请输入消息内容");
                    return;
                }
                String currentChatFriendJson = InfoRecord.getCurrentChatFriendJson();
                if ("".equals(currentChatFriendJson)) {
                    ToastUtils.showShort("请打开菜单选择好友聊天");
                    return;
                }
                FriendModel friendModel = new Gson().fromJson(currentChatFriendJson, FriendModel.class);
                mPresenter.sendMessage(messageStr, friendModel.getFriendId());
                et_input_message.setText("");
                TbMessage message = new TbMessage();
                message.setMessageFromUserId(Integer.valueOf(InfoRecord.getUserId()));
                message.setMessageContent(messageStr);
                message.setMessageToUserId(friendModel.getFriendId());
                mAdapterRvChat.addMessage(message);
                rv_chat.smoothScrollToPosition(mAdapterRvChat.getItemCount() - 1);
            }
        });
    }

    private int mOldSoftInputHeight;

    private boolean mIsInputMoving = false;

    private void moveDownInput() {
        if (!mIsInputBeTop && !mIsInputMoving) {
            return;
        }
        LogUtils.e("move down");
        mIsInputBeTop = false;
        final ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) rl_chat_container.getLayoutParams();
        int originMarginBottom = marginLayoutParams.bottomMargin;
        ValueAnimator animator = ValueAnimator.ofInt(originMarginBottom, 0);
        animator.addUpdateListener(animation -> {
            int currentMarginBottom = (int) animation.getAnimatedValue();
            if (currentMarginBottom == 0) {
                mIsInputMoving = false;
            } else {
                mIsInputMoving = true;
            }
            marginLayoutParams.setMargins(marginLayoutParams.leftMargin, marginLayoutParams.topMargin, marginLayoutParams.rightMargin, currentMarginBottom);
            rl_chat_container.setLayoutParams(marginLayoutParams);
        });
        animator.setInterpolator(new DecelerateInterpolator());
        animator.setDuration(100).start();
    }

    private void moveUpInput() {
        if (mIsInputBeTop && !mIsInputMoving) {
            return;
        }
        LogUtils.e("move up");
        mIsInputBeTop = true;
        final ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) rl_chat_container.getLayoutParams();
        ValueAnimator animator = ValueAnimator.ofInt(0, mSoftInputHeight - mNavigatorHeight);
        animator.addUpdateListener(animation -> {
            int currentMarginBottom = (int) animation.getAnimatedValue();
            if (currentMarginBottom == mSoftInputHeight - mNavigatorHeight) {
                mIsInputMoving = false;
//                mLinearLayoutManager.scrollToPositionWithOffset(mAdapterRvChat.getItemCount() - 1, Integer.MIN_VALUE);
//                mLinearLayoutManager.scrollToPositionWithOffset(mAdapterRvChat.getItemCount() - 1, 0);
                mLinearLayoutManager.scrollToPosition(mAdapterRvChat.getItemCount() - 1);
                rv_chat.stopScroll();
//                mLinearLayoutManager.scrollToPosition(mLinearLayoutManager.findLastCompletelyVisibleItemPosition());
//                rv_chat.smoothScrollToPosition(mAdapterRvChat.getItemCount() - 1);
            } else {
                mIsInputMoving = true;
            }
            marginLayoutParams.setMargins(marginLayoutParams.leftMargin, marginLayoutParams.topMargin, marginLayoutParams.rightMargin, currentMarginBottom);
            rl_chat_container.setLayoutParams(marginLayoutParams);
        });
        animator.setInterpolator(new DecelerateInterpolator());
        animator.setDuration(100).start();
    }


    @Override
    protected void process() {
        InfoRecord.setChatBackgroundImagePath(Environment.getExternalStorageDirectory().getPath() + "/asdasd1561.jpg");
        mPresenter.getUserInfo(InfoRecord.getUserId());
        mPresenter.getHasNewFriend();
        mPresenter.refreshFriendList();
        mPresenter.bindIMService(getApplicationContext(), BIND_AUTO_CREATE);
        LocationUtils.getInstance().init(ZingApplication.getAppContext());
        LocationUtils.getInstance().startLocationPost();
    }

    @Override
    protected int inflateContentView() {
        return R.layout.aty_chat;
    }

    @Override
    protected ChatPresenter createPresenter() {
        return new ChatPresenter();
    }

    @Override
    protected void setViewListener() {
        findViewById(R.id.iv_menu).setOnClickListener(this);

        mLeftMenuBuilder.setOnLeftMenuListener(new OnLeftMenuListener() {
            @Override
            public void onUploadNickname() {
                mPresenter.uploadNickname(AtyChat.this);
            }

            @Override
            public void onAddFriend() {
                mPresenter.addFriend(AtyChat.this);
            }

            @Override
            public void onShowFriendApplyList() {
                mPresenter.showFriendApplyList(AtyChat.this);
            }
        });
        mLeftMenuBuilder.setOnFriendChooseChangeListener(new OnFriendChooseChangeListener() {
            @Override
            public void onFriendChooseChangeListener(FriendModel friendModel) {
                mPresenter.setCurrentChatFriend(friendModel);
            }
        });

        srl_chat.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                String currentChatFriendJson = InfoRecord.getCurrentChatFriendJson();
                if (StringUtils.isEmpty(currentChatFriendJson)) {
                    srl_chat.setRefreshing(false);
                    return;
                }
                FriendModel friendModel = new Gson().fromJson(currentChatFriendJson, FriendModel.class);
                Integer friendId = friendModel.getFriendId();
                mPresenter.getHistoryMessage(friendId, mAdapterRvChat.getItemCount(), 10, friendModel);
            }
        });

        rl_new_message.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                rv_chat.smoothScrollToPosition(mAdapterRvChat.getItemCount() - 1);
            }
        });

        rv_chat.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                int totalCount = mLinearLayoutManager.getItemCount();
                if (totalCount > 1 && mLastVisibleItem == (totalCount - 1)) {
                    hideNewMessagePrompt();
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (mLinearLayoutManager != null) {
                    mLastVisibleItem = mLinearLayoutManager.findLastVisibleItemPosition();
                }
            }
        });

        iv_setting.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ToastUtils.showShort("先别点我~");
            }
        });
    }

    private int mLastVisibleItem;

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_menu:
                mLeftMenuBuilder.setFriendList().openMenu();
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case LeftMenu.Builder.PICK_PHOTO:
                if (resultCode == RESULT_OK) { // 判断手机系统版本号
                    if (Build.VERSION.SDK_INT >= 19) {
                        // 4.4及以上系统使用这个方法处理图片
                        handleImageOnKitKat(data);
                    } else {
                        // 4.4以下系统使用这个方法处理图片
                        handleImageBeforeKitKat(data);
                    }
                }
                break;
            default:
                break;
        }
    }

    @TargetApi(19)
    private void handleImageOnKitKat(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
        if (DocumentsContract.isDocumentUri(this, uri)) {
            // 如果是document类型的Uri，则通过document id处理
            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1];
                // 解析出数字格式的id
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content: //downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是content类型的Uri，则使用普通方式处理
            imagePath = getImagePath(uri, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            // 如果是file类型的Uri，直接获取图片路径即可
            imagePath = uri.getPath();
        }
        // 根据图片路径显示图片
        uploadAvatar(imagePath);
    }

    /**
     * android 4.4以前的处理方式
     *
     * @param data
     */
    private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        uploadAvatar(imagePath);
    }

    private String getImagePath(Uri uri, String selection) {
        String path = null;
        // 通过Uri和selection来获取真实的图片路径
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

    private void uploadAvatar(String imagePath) {
        if (imagePath != null) {
            LogUtils.e("imagePath == " + imagePath);
            String userId = InfoRecord.getUserId();
            if (StringUtils.isEmpty(userId)) {
                ToastUtils.showShort("userId不合法");
                return;
            }
            mPresenter.uploadAvatar(imagePath, userId);
        } else {
            ToastUtils.showShort("选取图片失败");
        }
    }

    @Override
    public void updateAvatar(String avatarUrlPath) {
        mLeftMenuBuilder.setAvatar(HttpConfig.PIC_ROOT + avatarUrlPath);
    }

    @Override
    public void updateNickname(String nickname) {
        mLeftMenuBuilder.setNickname(nickname);
    }

    @Override
    public void onAddFriendResponse(String message) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                toast(message);
            }
        });
    }

    @Override
    public void onNewFriendApplyToastAndUpdateMenuUI(String fromUsername) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                toast("Zing提醒您，收到新的好友申请");
                if (InfoRecord.getHasNewFriend()) {
                    mLeftMenuBuilder.setHasNewFriendDot();
                    view_dot.setVisibility(View.VISIBLE);
                }

            }
        });
    }

    @Override
    public void refreshFriendList(List<FriendModel> friendList) {
        mLeftMenuBuilder.refreshFriendList(friendList);
    }

    @Override
    public void messageSendSuccess(TbMessage message) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                LogUtils.e("message == " + message);
                if (message.getMessageStatus() == DataType.MESSAGE_TYPE_STATUS_SEND_FAIL) {
                    toast("发送消息失败");
                } else {
                    toast("发送消息成功");
                    mPresenter.refreshFriendList();
                }
            }
        });
    }

    @Override
    public void onReceiveMessage(TbMessage message) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mAdapterRvChat.addMessage(message);
                // 判断是否移动到最后一条
                if (mLinearLayoutManager.findLastVisibleItemPosition() == mAdapterRvChat.getItemCount() - 2) {
                    rv_chat.smoothScrollToPosition(mAdapterRvChat.getItemCount() - 1);
                } else {
                    // 显示有新消息提示
                    showNewMessagePrompt();
                }
                mPresenter.refreshFriendList();
            }
        });
    }

    private void showNewMessagePrompt() {
        rl_new_message.setVisibility(View.VISIBLE);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(
                ObjectAnimator.ofFloat(rl_new_message, "translationX", 0, -SizeUtils.dp2px(60)),
                ObjectAnimator.ofFloat(rl_new_message, "scaleX", 0, 1f),
//                ObjectAnimator.ofFloat(rl_new_message, "scaleY", 0, 1f),
                ObjectAnimator.ofFloat(rl_new_message, "alpha", 0, 1f)
        );
        animatorSet.setDuration(200).setStartDelay(0);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animatorSet.start();
    }

    private void hideNewMessagePrompt() {
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(
                ObjectAnimator.ofFloat(rl_new_message, "translationX", -SizeUtils.dp2px(60), 0),
                ObjectAnimator.ofFloat(rl_new_message, "scaleX", 1f, 0),
//                ObjectAnimator.ofFloat(rl_new_message, "scaleY", 1f, 0),
                ObjectAnimator.ofFloat(rl_new_message, "alpha", 1f, 0)
        );
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                rl_new_message.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animatorSet.setDuration(200).setStartDelay(0);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animatorSet.start();
    }

    @Override
    public void setCurrentChatFriendInfo(FriendModel friendModel) {
        String friendNickname = friendModel.getFriendNickname();
        if (StringUtils.isEmpty(friendNickname)) {
            tv_friend.setText(friendModel.getFriendUsername());
        } else {
            tv_friend.setText(friendNickname);
        }
    }

    @Override
    public void loadMessage(List<TbMessage> messageList, FriendModel friendModel) {
        mAdapterRvChat.clearAndNotifyMessageListChanged(messageList, friendModel, mLinearLayoutManager);
    }

    @Override
    public void loadHistoryMessage(List<TbMessage> messageList, FriendModel friendModel) {
        if (srl_chat.isRefreshing()) {
            srl_chat.setRefreshing(false);
        }
        mAdapterRvChat.addHistoryMessage(messageList);
//        rv_chat.smoothScrollToPosition(messageList.size() - 1);
        rv_chat.smoothScrollBy(0, SizeUtils.dp2px(-30));
    }

    @Override
    public void stopRefresh() {
        if (srl_chat.isRefreshing()) {
            srl_chat.setRefreshing(false);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mPresenter.changeActivityStatus(BasePresenter.ACTIVITY_STATUS_HIDE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // activity不再可见
        mPresenter.changeActivityStatus(BasePresenter.ACTIVITY_STATUS_HIDE);
    }

    @Override
    protected void onResume() {
        // activity在前台
        mPresenter.changeActivityStatus(BasePresenter.ACTIVITY_STATUS_FRONT);
        makeEditTextNoFocus();

        super.onResume();
    }

    private void makeEditTextNoFocus() {
        // 避免edit text自动获取焦点
        rl_chat_container.setFocusable(true);
        rl_chat_container.setFocusableInTouchMode(true);
        rl_chat_container.requestFocus();
    }
}
